from Clouds import CloudsRECCo
import numpy as np

class EvolveRECCo(object):
	
	def __init__(self, dim):
		self.cloudList    = []
		self.dimension    = dim
		self.memberVector = []     # OUTPUT: Vector of membership functions
		self.status       = False  # OUTPUT: Status of adding new cloud
		self.n_add        = 20
		self.c_max        = 20
		self.gama_max     = 0.93
		
	def addPoint(self, data, idxK):
		self.status = False
		gama_max    = self.gama_max
		c_max       = self.c_max
		n_add       = self.n_add
		numClouds   = len(self.cloudList)
		
		
		if idxK==1:
			self.cloudList.append(0)
			self.cloudList[0] = CloudsRECCo(data, 1)
			self.memberVector = np.array([1])
			self.status       = True
		else:
			if idxK==2:
				mi  = np.array([0,0])
				mi  = self.cloudList[0].mi
				var = self.cloudList[0].var
				Mj  = self.cloudList[0].Mj
						 
				mi  = ((Mj-1)/Mj)*mi  + (1/Mj)*data
				var = ((Mj-1)/Mj)*var + (1/Mj)*data.dot(data)
				#radii = math.sqrt(abs(mi.dot(mi)-var+(1-gama_max)/gama_max))
				
				self.cloudList[0].updateCloud(mi, var, 2, idxK)
				self.memberVector = np.array([1])
			else:
				gamaList = np.zeros(numClouds)
				kAddList = np.zeros(numClouds)
				for idx in range(numClouds):
					mi   = self.cloudList[idx].mi
					var  = self.cloudList[idx].var
					gama = 1/(1 + (data-mi).dot(data-mi) + var - mi.dot(mi))
					
					gamaList[idx] = gama
					kAddList[idx] = self.cloudList[idx].k_add
			
				if gama_max>max(gamaList) and c_max > numClouds and n_add < (idxK-max(kAddList)):
				# ADDING NEW CLOUD
					#print("\t\tNew cloud added at ", idxK, " timestamp")
					print("\r New cloud added at ", idxK, " timestamp")
					self.cloudList.append(0)
					self.cloudList[-1] = CloudsRECCo(data, idxK)
					self.status        = True
					self.memberVector  = np.hstack((self.memberVector,1))
					gamaList           = np.hstack((gamaList,1))
				
				else:
				# ASSIGNING DATA WTIH EXISTING CLOUD
					idxC = np.argmax(gamaList)
					mi   = np.array([0,0])
					mi   = self.cloudList[idxC].mi
					var  = self.cloudList[idxC].var
					Mj   = self.cloudList[idxC].Mj + 1

					mi   = ((Mj-1)/Mj)*mi  + (1/Mj)*data
					var  = ((Mj-1)/Mj)*var + (1/Mj)*data.dot(data)
					#radii = math.sqrt(abs(mi.dot(mi)-var+(1-gama_max)/gama_max))
					
					self.cloudList[idxC].updateCloud(mi, var, Mj, idxK)
					
				self.memberVector = gamaList/(np.sum(gamaList))
